import React from 'react';
class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            counter: 0
        };
    }
    componentDidMount() {
        //counter1 打印出来的是0 HTML 渲染中是1，
        // setState在生命周期中是异步的，
        // this.changeValue(1);


        //counter1 打印出来的是1 HTML 渲染中是1
        //setState在原生事件是同步的
        document.getElementById("test").addEventListener('click', this.setCounter);
    }
    changeValue = v => {
        // counter1 打印出来的是0 HTML 渲染中是1，
        //所以可以看出来
        // setState在合成事件中是异步的，这里说的异步其实是批量更新，达到了优化性能的目的
        // this.setState({
        //     counter: this.state.counter + v
        // }, () => {
        //     // state更新之后被执行
        //     console.log("counter2：", this.state.counter);
        // });
        // console.log("counter1：", this.state.counter);
        this.setState(state => {
            return {
                counter: state.counter + v
            }

        });
    };
    setCounter = () => {
        // 只打印出counter2 ：2,4,6，这样看的只执行了this.changeValue(2);没有执行this.changeValue(1);，
        //这是批量更新。批量更新的话 是方法一起执行，然后每次都是修改counter，key值是相同的，所以最后可能会覆盖前面的值
        this.changeValue(1);
        this.changeValue(2);
        // counter1 打印出来的是1 HTML 渲染中是1
        //setState在setTimeout是同步的
        // setTimeout(() => {
        //     this.changeValue(1);
        // }, 0);
    };
    render() {
        const { counter } = this.state;
        return (
            <div>
                <h1>正确使⽤setState</h1>
                <button onClick={this.setCounter}>{counter}</button>
                <button id="test">原生事件：{counter}</button>
            </div>
        )
    }
}
export default App;
/*
# 正确使⽤setState
    setState(partialState, callback)
    1. partialState : object|function
    ⽤于产⽣与当前state合并的⼦集。
    2. callback : function
    state更新之后被调⽤。
# 关于 setState() setState() 你应该了解三件事：
1.不要直接修改 State
    // 错误示范 这个不是异步的操作
    this.state.comment = 'Hello';
    // 正确使⽤
    this.setState({comment: 'Hello'});

2.State 的更新可能是异步的:出于性能考虑，React 可能会把多个 setState() 调⽤合并成⼀个调⽤。

eg： 观察以下例⼦中log的值和button显示的counter:
<button onClick={this.setCounter}>{counter}</button>

3.State 的更新会被合并

    setCounter = () => {
        // 只打印出counter2 ：2,4,6，这样看的只执行了this.changeValue(2);没有执行this.changeValue(1);，
        //这是批量更新。批量更新的话 是方法一起执行，然后每次都是修改counter，key值是相同的，所以最后可能会覆盖前面的值
        //所以 State 的更新会被合并
        this.changeValue(1);
        this.changeValue(2);
    };
    如果就是想 链式更新state，执行1，然后执行2
    changeValue = v => {
        this.setState(state => {
            return {
                counter: state.counter + v
            }

        });
    };

# 如果要获取到最新状态值有以下⽅式：
1. 在回调中获取状态值
    changeValue = v => {
        this.setState({
            counter: this.state.counter + v
        },() => {
            console.log("counter", this.state.counter);
        });
    };
2. 使⽤定时器：
    setTimeout(() => {
     this.setCounter();
    }, 0);

3. 原⽣事件中修改状态
componentDidMount(){
 document.body.addEventListener('click', this.changeValue, false)
}

总结： setState只有在合成事件和⽣命周期函数中是异步的，在原⽣事件和setTimeout中都是同步
的，同时setstate自身有一个回调函数也是可以直接获取state的值 ，这⾥的异步其实是批量更新。同步的意思是 setstate修改完state的值后，就可以立马拿到state的值（这里不是直接从setstate的回调取）
*/